home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
video
/
fly8111-.000
/
fly8111-
/
fly8
/
max.c
< prev
next >
Wrap
C/C++ Source or Header
|
1979-12-31
|
7KB
|
411 lines
/* --------------------------------- max.c ---------------------------------- */
/* This is part of the flight simulator 'fly8'.
* Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
*/
/* Read a text macro definition. Directly replaces mac_read() of macros.c.
*/
#include "fly.h"
#include "keyname.h"
static Ulong lineno = 1L, column = 0L, errs = 0L;
static int eof = 1, pushback = 0;
static int pushbuff[10] = {0};
static char tabCTRL[] = "@abcdefghijklmnopqrstuvwxyz[\\]^_";
static Ushort buf_str[1024] = {0};
LOCAL_FUNC int NEAR
keyval (int c)
{
if (c >= 0 && c < 32)
c = tabCTRL[c] | K_CTRL;
return (c);
}
LOCAL_FUNC int NEAR
nlfgetc (FILE *f)
{
int c;
if (pushback) {
c = pushbuff[--pushback];
return (c);
}
if (eof)
return (EOF);
c = fgetc (f);
++column;
if ('\n' == c) {
++lineno;
column = 0;
} else if (EOF == c)
eof = 1;
return (c);
}
LOCAL_FUNC Ulong NEAR
eatline (FILE *f)
{
int c;
do {
c = nlfgetc (f);
} while (EOF != c && '\n' != c);
return (EOF == c ? VK_EOF : (Ulong)c);
}
LOCAL_FUNC int NEAR
getbase (FILE *f, int base, int n, int c)
{
int i;
for (i = 0;;) {
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'a' && c <= 'f')
c -= 'a' - 10;
else if (c >= 'A' && c <= 'F')
c -= 'A' - 10;
else {
pushbuff[pushback++] = c;
break;
}
if (c >= base)
break;
i = i * base + c;
if (--n < 0)
break;
c = nlfgetc (f);
}
if (i >= 256) {
++errs;
MsgEPrintf (-50,
"max: escaped value too big at %ld:%ld",
lineno, column);
i &= 0x00ff;
}
return (i);
}
LOCAL_FUNC int NEAR
getescape (FILE *f)
{
int c;
c = nlfgetc (f);
switch (c) {
case 'a':
c = 'g';
break;
case 'b':
c = 'h';
break;
case 'e':
c = '[';
break;
case 'f':
c = 'l';
break;
case 'n':
c = 'm';
break;
case 'r':
c = 'j';
break;
case 't':
c = 'i';
break;
case 'v':
c = 'k';
break;
case '\n':
c = -1; /* traditional line break */
goto raw;
case '0':
c = keyval (getbase (f, 8, 3, '0'));
goto raw;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
c = keyval (getbase (f, 10, 2, c));
goto raw;
case 'x':
c = keyval (getbase (f, 16, 2, '0'));
goto raw;
default:
goto raw;
}
c |= K_CTRL;
raw:
return (c);
}
LOCAL_FUNC int NEAR
getstring (FILE *f)
{
int c, n;
for (n = 0;;) {
c = nlfgetc (f);
if (EOF == c) {
++errs;
MsgEPrintf (-50, "max: EOF inside string at %ld:%ld",
lineno, column);
n = -1;
break;
}
if ('\\' == c) {
c = getescape (f);
if (-1 == c)
continue;
} else if ('"' == c)
break;
else if ('\n' == c) /* simplified line break */
continue;
else
c = keyval (c);
if (n >= rangeof (buf_str)) {
++errs;
MsgEPrintf (-50, "max: string too long at %ld:%ld",
lineno, column);
continue;
}
buf_str[n++] = (Ushort)c;
}
return (n);
}
LOCAL_FUNC Ulong NEAR
getterm (FILE *f)
{
char keyname[32+1];
int n, i, c;
retry:
for (n = 0;;) {
c = nlfgetc (f);
if (EOF == c) {
if (n)
break;
return (VK_EOF);
}
if (isspace (c)) {
if (n)
break;
continue;
}
if ('\\' == c) {
if (n) {
++errs;
MsgEPrintf (-50, "max: bad escape at %ld:%ld",
lineno, column);
continue;
}
c = getescape (f);
if (-1 == c)
continue;
return (c);
}
if (n < sizeof (keyname) - 1) {
if (0 == n) {
if ('"' == c)
return (VK_STR);
if ('#' == c)
return (VK_COM);
}
keyname[n++] = (char)c;
} else
{/* truncate... */}
}
keyname[n] = '\0';
/* Look word up
*/
for (i = 0; k_name[i].name; ++i) {
if (!stricmp (k_name[i].name, keyname))
return (k_name[i].value);
}
if (1 == n)
return (keyval(*(Uchar *)keyname));
++errs;
MsgEPrintf (-50, "max: bad token '%s' at %ld:%ld", keyname,
lineno, column);
if (EOF == c)
return (VK_EOF);
goto retry;
}
LOCAL_FUNC Ulong NEAR
maxkey (FILE *f)
{
Ulong c, key;
for (key = 0L;;) {
c = getterm (f);
if (VK_EOF == c) {
if (key) {
++errs;
MsgEPrintf (-50,
"max: unexpected end of file at %ld:%ld",
lineno, column);
}
return (VK_EOF);
} else if (VK_DEF == c) {
if (key) {
++errs;
MsgEPrintf (-50,
"max: bad key preceding 'def' at %ld:%ld",
lineno, column);
}
key = VK_DEF;
} else if (VK_COM == c) {
if (key) {
++errs;
MsgEPrintf (-50,
"max: bad key preceding comment at %ld:%ld",
lineno, column);
}
key = 0L;
c = eatline (f);
if (VK_EOF == c)
return (VK_EOF);
} else if (VK_STR == c) {
if (key) {
++errs;
MsgEPrintf (-50,
"max: bad key preceding string at %ld:%ld",
lineno, column);
}
return (VK_STR);
} else {
key |= c;
if (c & K_RAW)
return (key);
}
}
/* never reached */
}
#define MAXMACLEN 1024
extern int FAR
max_read (MACRO *Macros)
{
FILE *max = NULL;
int i, n, nMacros;
Ulong c;
MACRO *m;
Ushort *macbody;
macbody = (Ushort *)memory_calloc (MAXMACLEN, sizeof (*macbody));
Sys->BuildFileName (st.filename, st.fdir, st.mname, MAX_EXT);
max = fopen (st.filename, RTMODE);
if (!max) {
MsgEPrintf (-50, "max: open '%s' failed",
st.filename);
++errs;
goto ret;
}
eof = 0;
pushback = 0;
LogPrintf ("Max %s\n", st.filename);
for (m = Macros, nMacros = 0;;) {
c = maxkey (max);
if (VK_EOF == c)
break;
if (!(VK_DEF & c)) {
++errs;
MsgEPrintf (-50, "max: 'def' not found at %ld:%ld",
lineno, column);
continue;
}
def:
if (nMacros > st.nMacros) {
++errs;
MsgEPrintf (-50, "max: too many macros at %ld:%ld",
lineno, column);
break;
}
m->name = (Ushort)c;
for (n = 0;;) {
c = maxkey (max);
if (VK_EOF == c || (VK_DEF & c))
break;
if (VK_STR == c) {
i = getstring (max);
if (i <= 0)
continue;
if (n+i > MAXMACLEN) {
++errs;
MsgEPrintf (-50,
"max: macro too long at %ld:%ld", lineno, column);
} else {
memcpy (macbody+n, buf_str,
i * sizeof (Ushort));
n += i;
}
continue;
}
if (n >= MAXMACLEN) {
++errs;
MsgEPrintf (-50,
"max: macro too long at %ld:%ld",
lineno, column);
continue;
}
macbody[n++] = (Ushort)c;
}
if (0 == n) {
++errs;
MsgEPrintf (-50, "max: empty macro at %ld:%ld",
lineno, column);
}
m->len = (Ushort)n;
m->def = (Ushort *)memory_calloc (m->len, sizeof (*m->def));
if (!m->def) {
++errs;
MsgEPrintf (-50, "max: no mem");
m->name = KEYUNUSED;
goto ret;
}
memcpy (m->def, macbody, m->len * sizeof (*m->def));
++m;
++nMacros;
if (VK_DEF & c)
goto def;
if (VK_EOF == c)
break;
}
ret:
if (max) {
fclose (max);
max = NULL;
}
eof = 1;
pushback = 0;
macbody = memory_cfree (macbody, MAXMACLEN, sizeof (*macbody));
return (0 != errs);
}
#undef MAXMACLEN